// Vue的nextTick的实现经过了多次的调整。在Vue2.5以前，nextTick优先使用微任务Promise来实现。到了2.5版本，
// Vue引入MessageChannel，nextTick的实现优先使用setImmediate，平台不支持则使用MessageChannel，
// 再不支持才使用Promise，最后用setTimeout兜底。

// 不过到了2.6版本以后，nextTick又改回原来的Promise实现。虽然MessageChannel只存在了一个minor版本，
// 但是我们从Vue的使用上知道它可以用来控制异步任务的执行时机。

function nexTick() {
  if (typeof setImmediate !== "undefined" && isNative(setImmediate)) {
    timerFunc = () => {
      setImmediate(nextTickHandler);
    };
  } else if (
    typeof MessageChannel !== "undefined" &&
    (isNative(MessageChannel) ||
      MessageChannel.toString() === "[object MessageChannelConstructor]")
  ) {
    const channel = new MessageChannel();
    const port = channel.port2;
    channel.port1.onmessage = nextTickHandler;
    timerFunc = () => {
      port.postMessage(1);
    };
  } else if (typeof Promise !== "undefined" && isNative(Promise)) {
    const p = Promise.resolve();
    timerFunc = () => {
      p.then(nextTickHandler);
    };
  } else {
    timerFunc = () => {
      setTimeout(nextTickHandler, 0);
    };
  }
}
